Type inference in conditional types
from Conditional Types
infer Rのこと
この宣言で、新たな型引数Rが導入される
genericsの引数に指定せずに、新たな型引数を導入できる
(右辺の)extendsの右辺にしか書けないことに注意するmrsekut.icon
(右辺の)extendsの右辺にしか書けないことに注意する
そもそもConditional Typesは、=の右辺の話である
だから例えば、
code:ts
type Hoge<ここには書けない> = ..
type Hoge<T extends ここには書けない> = ..
type Hoge<..> = ここには書けない extends .. ? .. : ..
type Hoge<..> = .. extends ここに書ける ? .. : ..
もっと具体的には、
code:ts
// ok
type Head<T extends any[]> = T extends [any, ...any[]] ? T0 : never;
// inferはgenericsの話ではないのでng
type Head<T extends any[], [infer H, ...any[]] extends T> = H
// conditional typesだけど、extendsの左辺で使っているのでsyntax error
type Head<T extends any[]> = [infer H, ...any[]] extends T ? H : never
#WIP
例
code:ts
// 複数使用できる
type Function<F> = F extends (...args: infer A) => infer R ? A, R : never;
const f = (a: number, b: string) => true;
type F = Function<typeof f>; // [number, string, boolean]
code:ts
type Array<T> = T extends (infer U)[] ? U : never;
const array = 1, 'hoge', true;
type A = Array<typeof array>; // string | number | boolean
ReturnType<Fn>はFnが関数の型なら、その返り値の型
code:ts
type ReturnType<T extends (...args: any[]) => any> = T extends (
...args: any[]
) => infer R
? R
: any;
「関数の戻り値の部分」にRという名前を付けて、then節のところで再利用している
infer T extends ..
https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a#conditional-typeにおける型マッチング
https://qiita.com/ringtail003/items/733aff32ddad7d4fda90